﻿using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System;

namespace FscNET.Tracer
{
    using Tracing;
    using Apm;
    using System.Diagnostics;
    public partial class Main
    {
        private TraceOutput _traceOutput = OutputManager.TraceOutput;
        private ToolStripMenuItem[] _miDefault;
        private ToolStripMenuItem[] _miAll;
        private const string ResourceName = "CooTraceMapEditor.exe";
        private void InitializeMenuItemGroups()
        {
                _miDefault = new ToolStripMenuItem[]{
                miOutputProcess, miOutputThread, miOutputModule
            };
            _miAll = new ToolStripMenuItem[]{
                miOutputProcess, miOutputThread, miOutputModule, miOutputProject,
                miOutputFunction, miOutputFile, miOutputLine, miOutputStack, miOutputUser
            };
        }

        private Action<ToolStripMenuItem> _actDeselect = delegate(ToolStripMenuItem mi)
        {
            if (mi == null) return;
            mi.Checked = false;
        };
        private Action<ToolStripMenuItem> _actSelect = delegate(ToolStripMenuItem mi)
        {
            if (mi == null) return;
            mi.Checked = true;
        };
        Predicate<string> _resourcePredicate = delegate(string s)
        {
            if (s == null || s.Trim().Length == 0) return false;
            return s.EndsWith(ResourceName);
        };
        private void miOutput_DropDownClosing(object sender, ToolStripDropDownClosingEventArgs args)
        {
            if (args.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
                args.Cancel = true;
            else
            {
                if (OutputManager.TraceOutput == _traceOutput) return;
                OutputManager.TraceOutput = _traceOutput;
                SetColumnsVisibility();
                if (miOutputSession0.Checked)
                {
                    string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
                    string name = Array.Find(names, _resourcePredicate);
                    Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
                    
                    if(!File.Exists(ResourceName))
                        using (FileStream f = File.Open(ResourceName, FileMode.Create))
                        {
                            byte[] buffer = new byte[s.Length];
                            s.Read(buffer, 0, (int)s.Length);
                            f.Write(buffer, 0, (int)s.Length);
                        }

                    System.Diagnostics.ProcessStartInfo start =
                        new System.Diagnostics.ProcessStartInfo();
                    start.FileName = "PsExec.exe";
                    //start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    start.Arguments = " -i 0 -c " + ResourceName + " " + ((int)_traceOutput).ToString();

                    using (new WaitCursor(this))
                    {
                        Process p = Process.Start(start);
                        p.WaitForExit(3000);
                    }
                }
            }
        }

        private void miOutput_DropDownItemCLicked(object sender, ToolStripItemClickedEventArgs args)
        {
            TraceOutput val;
            switch(args.ClickedItem.Name)
            {
                case "miOutputProcess":
                    val = TraceOutput.Process;
                    break;
                case "miOutputThread":
                    val = TraceOutput.Thread;
                    break;
                case "miOutputModule":
                    val = TraceOutput.Module;
                    break;
                case "miOutputProject":
                    val = TraceOutput.Project;
                    break;
                case "miOutputFunction":
                    val = TraceOutput.Function;
                    break;
                case "miOutputFile":
                    val = TraceOutput.File;
                    break;
                case "miOutputLine":
                    val = TraceOutput.Line;
                    break;
                case "miOutputStack":
                    val = TraceOutput.Stack;
                    break;
                case "miOutputUser":
                    val = TraceOutput.User;
                    break;
                case "miOutputDefault":
                    val = TraceOutput.Default;
                    Array.ForEach(_miAll, _actDeselect);
                    Array.ForEach(_miDefault, _actSelect);
                    break;
                case "miOutputNone":
                    val = TraceOutput.None;
                    Array.ForEach(_miAll, _actDeselect);
                    break;
                case "miOutputAll":
                    val = TraceOutput.AllExt;
                    Array.ForEach(_miAll, _actSelect);
                    break;
                default:
                    return;
            }
            if (((ToolStripMenuItem)args.ClickedItem).CheckState == CheckState.Checked) //old value
                _traceOutput &= ~val;
            else
                _traceOutput |= val;
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            _pipeList.ForEach(delegate(NamedPipes.NamedPipeServerStream pipe)
            {
                if (pipe.IsConnected) pipe.Disconnect();
            });
        }

        private void TEST(object sender, EventArgs args)
        {

            CMemoryMappedFile mappedFile = new CMemoryMappedFile("CooTraceMap");
            //int hodnota = mappedFile.ReadInt32(0);

            mappedFile.WriteInt32(7, 0);

            _pipeList.RemoveAll(delegate(NamedPipes.NamedPipeServerStream pipe) {
                if (pipe.IsConnected)
                {
                    pipe.Disconnect();
                    return true;
                }
                return false;
            });
            
            if (_pipeList.Count == 0)
            {
                AsyncEnumerator ae = new AsyncEnumerator();
                ae.BeginExecute(PipeServerEnumerator(ae), ae.EndExecute);
            }

            //_pipeList.Clear();
        }
    }
}
